package com.guisu.animation.loading.multi_shape_loading

import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Context
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import android.widget.LinearLayout
import androidx.core.animation.addListener
import com.guisu.animation.R

class LoadingView: LinearLayout {

    private var mShapeView: ShapeView? = null
    private var mShadowView: View? = null

    private var mTranslationDistance = 0
    private val ANIMATOR_DURATION = 350L

    private var mIsStopAnimator = false

    constructor(context: Context): this(context, null)
    constructor(context: Context, attributeSet: AttributeSet?): this(context, attributeSet, 0)
    constructor(context: Context, attributeSet: AttributeSet?, defStyleAttr: Int): super(context, attributeSet, defStyleAttr) {
        mTranslationDistance = dip2Px(160)
        initData(context, attributeSet)
    }

    private fun dip2Px(i: Int): Int {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, i.toFloat(), resources.displayMetrics).toInt()
    }

    private fun initData(context: Context, attributeSet: AttributeSet?) {
        // 1. 加载写好的 ui_loading_view
        // 1.1 实例化view
//        val loadView = inflate(context, R.layout.ui_loading_view, null)
        // 1.2 添加到该view
//        addView(loadView)
        inflate(context, R.layout.ui_loading_view, this) //加载到this里面

        mShapeView = findViewById(R.id.shape_view)
        mShadowView = findViewById(R.id.shadow_view)

        post {
            // 下落
            startFallAnimator()
        }
    }

    // 开始下落动画
    private fun startFallAnimator() {
        if (mIsStopAnimator) {
            return
        }
        // 动画作用在谁的身上
        // 下落位移动画
        val translation = ObjectAnimator.ofFloat(mShapeView!!, "translationY", 0f,mTranslationDistance.toFloat())
        // 组合中间阴影缩小
        val scale = ObjectAnimator.ofFloat(mShadowView!!, "scaleX", 1f, 0.3f)

        val animatorSet = AnimatorSet().apply {
            duration = ANIMATOR_DURATION
            interpolator = AccelerateInterpolator()
            playTogether(translation, scale)
            start()
        }
        // 下落完之后就上抛了，监听动画执行完毕
        animatorSet.addListener(onEnd = {
            // 改变形状
            mShapeView?.exchange()
            // 下落完之后就上抛了
            startUpAnimator()
        })
    }

    // 开始执行上抛动画
    private fun startUpAnimator() {
        if (mIsStopAnimator) {
            return
        }
        // 动画作用在谁的身上
        // 上抛位移动画
        val translation = ObjectAnimator.ofFloat(mShapeView!!, "translationY", mTranslationDistance.toFloat(),0f)
        // 组合中间阴影缩小
        val scale = ObjectAnimator.ofFloat(mShadowView!!, "scaleX", 0.3f, 1f)

        val animatorSet = AnimatorSet().apply {
            interpolator = DecelerateInterpolator()
            duration = ANIMATOR_DURATION
            playTogether(translation, scale)
        }
        // 上抛完之后就下落了，监听动画执行完毕
        animatorSet.addListener(onStart = {
            // 开始旋转
            startRotationAnimator()
        }, onEnd = {
            // 上抛完之后就下落了
            startFallAnimator()
        })
        animatorSet.start()
    }

    // 上抛的时候需要旋转
    private fun startRotationAnimator() {
        val rotation = when (mShapeView!!.getCurrentShape()) {
            ShapeView.Shape.Circle, ShapeView.Shape.Square -> {
                // 180
                ObjectAnimator.ofFloat(mShapeView!!, "rotation", 0f, 180f)
            }
            ShapeView.Shape.Triangle -> {
                // 120
                ObjectAnimator.ofFloat(mShapeView!!, "rotation", 0f, -120f)
            }
        }
        rotation.apply {
            interpolator = DecelerateInterpolator()
            duration = ANIMATOR_DURATION
            start()
        }
    }

    override fun setVisibility(visibility: Int) {
        super.setVisibility(View.INVISIBLE) //不要再去摆放和计算，少走一些系统的源码
        // 清理动画
        mShapeView!!.clearAnimation()
        mShadowView!!.clearAnimation()

        // 把loadingView从父布局移除
        val parent = this.parent as ViewGroup
        parent.removeView(this)
        removeAllViews()

        mIsStopAnimator = true
    }
}